from enum import StrEnum
from flask_babel import _
from sqlalchemy import func
from models.engine import db
from models.robot.area_code import SystemAreaCode
from models.types import StringUUID

class TransfeeFreeType(StrEnum):
    """
    免运费类型
    """
    CONDITION = "C" # 满足条件
    AMOUNT = "A" # 满足金额
    BOTH = "B" # 满足金额和条件
    @property
    def label(self)->str|None:
        return {
            "C": _("Enum:TransfeeFreeType:Fit Condition"),
            "A": _("Enum:TransfeeFreeType:Fit Amount"),
            "B": _("Enum:TransfeeFreeType:Fit Condition and Amount"),
        }.get(self.value)

class TransportChargeType(StrEnum):
    """
    运费计算方式
    """
    AMOUNT = "A" # 按件数
    WEIGHT = "W" # 按重量
    VOLUME = "V" # 按体积
    @property
    def label(self)->str|None:
        return {
            "C": _("Enum:TransportChargeType:Amount"),
            "A": _("Enum:TransportChargeType:Weight"),
            "B": _("Enum:TransportChargeType:Volume"),
        }.get(self.value)

class MDeliveryComp(db.Model):
    __tablename__ = "sp_delivery"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="sp_delivery_pkey"),
        db.Index('sp_delivery_name_idx', 'name'),
    )
    id = db.Column(StringUUID,nullable=False,server_default=db.text("uuid_generate_v4()"), primary_key=True)
    name = db.Column(db.String(128),nullable=False)
    home_url = db.Column(db.String(512),nullable=True,comment="官网URL")
    query_url = db.Column(db.String(512),nullable=False,comment="查询URL")
    created_at = db.Column(db.TIMESTAMP,server_default=func.current_timestamp())
    created_by = db.Column(StringUUID,nullable=False)
    updated_at = db.Column(db.TIMESTAMP,server_default=func.current_timestamp())
    updated_by = db.Column(StringUUID,nullable=True)

class MPickAddr(db.Model):
    """
    用户自提点地址
    """
    __tablename__ = "sp_pick_addr"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="sp_pick_addr_pkey"),
        db.Index('sp_pick_addr_name_idx', 'name'),
    )
    id = db.Column(StringUUID,server_default=db.text("uuid_generate_v4()"), primary_key=True)
    tenant_id = db.Column(StringUUID,nullable=False,comment='租户ID')
    name = db.Column(db.String(128),nullable=False,comment="自提点名称")
    addr = db.Column(db.String(512),nullable=False,comment="地址")
    mobile = db.Column(db.String(32),nullable=False,comment="手机")
    province_id = db.Column(db.BigInteger,nullable=True,comment="省ID")
    province = db.Column(db.String(64),nullable=True,comment="省")
    city_id = db.Column(db.BigInteger,nullable=True,comment="市ID")
    city = db.Column(db.String(64),nullable=True,comment="市")
    district_id = db.Column(db.BigInteger,nullable=True,comment="区ID")
    district = db.Column(db.String(64),nullable=True,comment="区")
    shop_id = db.Column(StringUUID,nullable=True,comment="店铺ID")
    created_at = db.Column(db.TIMESTAMP,server_default=func.current_timestamp())
    created_by = db.Column(StringUUID,nullable=False)
    updated_at = db.Column(db.TIMESTAMP,server_default=func.current_timestamp())
    updated_by = db.Column(StringUUID,nullable=True)

class MUserAddr(db.Model):
    """
    用户收货地址
    """
    __tablename__ = "sp_user_addr"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="sp_user_addr_pkey"),
        db.Index('sp_user_addr_account_id_idx', 'account_id'),
    )

    id = db.Column(db.BigInteger,autoincrement=True, primary_key=True)
    tenant_id = db.Column(StringUUID, nullable=False,comment="租户ID")
    account_id = db.Column(StringUUID, nullable=False,comment="用户ID")
    receiver = db.Column(db.String(64), nullable=False,comment="收货人")
    mobile = db.Column(db.String(32), nullable=False,comment="手机")
    province_id = db.Column(db.BigInteger,nullable=True,comment="省ID")
    province = db.Column(db.String(64),nullable=True,comment="省")
    city_id = db.Column(db.BigInteger,nullable=True,comment="市ID")
    city = db.Column(db.String(64),nullable=True,comment="市")
    district_id = db.Column(db.BigInteger,nullable=True,comment="区ID")
    district = db.Column(db.String(64),nullable=True,comment="区")
    postal_code = db.Column(db.String(18), nullable=True,comment="邮编")
    addr = db.Column(db.String(512), nullable=False,comment="地址")
    status = db.Column(db.Boolean(),server_default=db.text("true"),comment="状态:true:正常,false:禁用")
    is_default = db.Column(db.Boolean(),server_default=db.text("false"),comment="是否默认:true:是,false:否")
    ver = db.Column(db.Integer,server_default=db.text('0'),comment="版本号")
    created_at = db.Column(db.TIMESTAMP,server_default=func.current_timestamp(),comment="创建时间")
    updated_at = db.Column(db.TIMESTAMP,comment="更新时间")


class MUserOrderAddr(db.Model):
    """
    用户订单配送地址
    """
    __tablename__ = "sp_user_addr_order"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="sp_user_addr_order_pkey"),
        db.Index('sp_user_addr_order_account_id_idx', 'account_id'),
    )
    id = db.Column(db.BigInteger,autoincrement=True, primary_key=True)
    user_addr_id = db.Column(db.BigInteger, nullable=False,comment="用户收货地址ID")
    account_id = db.Column(StringUUID, nullable=False,comment="用户ID")
    receiver = db.Column(db.String(64), nullable=False,comment="收货人")
    mobile = db.Column(db.String(32), nullable=False,comment="手机")
    province_id = db.Column(db.BigInteger,nullable=True,comment="省ID")
    province = db.Column(db.String(64),nullable=True,comment="省")
    city_id = db.Column(db.BigInteger,nullable=True,comment="市ID")
    city = db.Column(db.String(64),nullable=True,comment="市")
    district_id = db.Column(db.BigInteger,nullable=True,comment="区ID")
    district = db.Column(db.String(64),nullable=True,comment="区")
    postal_code = db.Column(db.String(18), nullable=True,comment="邮编")
    addr = db.Column(db.String(512), nullable=False,comment="地址")
    status = db.Column(db.Boolean(),server_default=db.text("true"),comment="状态:true:正常,false:禁用")
    is_default = db.Column(db.Boolean(),server_default=db.text("false"),comment="是否默认:true:是,false:否")
    ver = db.Column(db.Integer,server_default=db.text('0'),comment="版本号")
    created_at = db.Column(db.TIMESTAMP,server_default=func.current_timestamp(),comment="创建时间")


class MTransCity(db.Model):
    """
    配送城市-运费项
    """
    __tablename__ = "sp_transcity"
    __table_args__ = (
        db.PrimaryKeyConstraint('id',name='sp_transcity_pkey'),
        db.Index('sp_transcity_city_id_idx', 'city_id'),
        db.Index('sp_transcity_transfee_id_idx', 'transfee_id'),
    )
    id = db.Column(db.BigInteger,autoincrement=True, primary_key=True)
    transfee_id = db.Column(db.BigInteger, nullable=False,comment="运费项ID")
    city_id = db.Column(db.BigInteger, nullable=False,comment="城市ID")
    @property
    def city_name(self)->str|None:
        city_name = db.session.get(SystemAreaCode,self.city_id)
        return city_name.name if city_name else None

class MTransFreeCity(db.Model):
    """
    配送城市-免费
    """
    __tablename__ = "sp_transcity_free"
    __table_args__ = (
        db.PrimaryKeyConstraint('id',name='sp_transcity_free_pkey'),
        db.Index('sp_transcity_free_city_id_idx', 'city_id'),
        db.Index('sp_transcity_free_transfee_free_id_idx', 'transfee_free_id'),
    )
    id = db.Column(db.BigInteger,autoincrement=True, primary_key=True)
    transfee_free_id = db.Column(db.BigInteger, nullable=False,comment="免费项ID")
    city_id = db.Column(db.BigInteger, nullable=False,comment="城市ID")
    @property
    def city_name(self)->str|None:
        city_name = db.session.get(SystemAreaCode,self.city_id)
        return city_name.name if city_name else None
    
class MTransfeeFree(db.Model):
    """
    指定条件包邮项
    """
    __tablename__ = "sp_transfee_free"
    __table_args__ = (
        db.PrimaryKeyConstraint('id',name='sp_transfee_free_pkey'),
        db.Index('sp_transfee_free_transport_idx', 'transport_id'),
    )
    id = db.Column(db.BigInteger,autoincrement=True, primary_key=True)
    transport_id = db.Column(db.BigInteger, nullable=False,comment="运费模板ID")
    free_type = db.Column(db.String(1), nullable=False,comment="包邮方式 （C:0 满x件/重量/体积包邮 A:1满金额包邮 B:2满x件/重量/体积且满金额包邮）")
    amount = db.Column(db.Integer, nullable=True,comment="免费需满足金额")
    piece = db.Column(db.Float(precision=24), nullable=True,comment="免费需满足条件")
    @property
    def Amount(self)->float|None:
        if self.amount:
            return float(self.amount*1000)
        return None
    
    @Amount.setter
    def Amount(self,value:float):
        if value:
            self.amount = value*(1.0/1000.0)

    @property
    def city_list(self)->list[str]:
        transcity_fees = db.session.query(MTransFreeCity).filter(MTransFreeCity.transfee_free_id==self.id).all()
        if transcity_fees:
            return [fee.city_name for fee in transcity_fees if fee.city_name]
        return []
    
    @property
    def city_ids(self)->list[int]:
        transcity_fees = db.session.query(MTransFreeCity).filter(MTransFreeCity.transfee_free_id==self.id).all()
        if transcity_fees:
            return [fee.city_id for fee in transcity_fees if fee.city_id]
        return []

class MTransfee(db.Model):
    """
    运费项
    """
    __tablename__ = "sp_transfee"
    __table_args__ = (
        db.PrimaryKeyConstraint('id',name='sp_transfee_pkey'),
        db.Index('sp_transfee_transport_idx', 'transport_id'),
    )
    id = db.Column(db.BigInteger,autoincrement=True, primary_key=True)
    transport_id = db.Column(db.BigInteger, nullable=False,comment="运费模板ID")
    continuous_piece = db.Column(db.Float(precision=24,decimal_return_scale=2),comment="续重/续件数量")
    first_piece = db.Column(db.Float(precision=24,decimal_return_scale=2),comment="收件数量")
    continuous_fee = db.Column(db.Integer, nullable=True,comment="续件费用")
    first_fee = db.Column(db.Integer, nullable=True,comment="首件费用")

    @property
    def ContinuousFee(self)->float|None:
        if self.continuous_fee:
            return float(self.continuous_fee*1000)
        return None
    
    @ContinuousFee.setter
    def ContinuousFee(self,value:float):
        if value:
            self.continuous_fee = value*(1.0/1000.0)

    @property
    def FirstFee(self)->float|None:
        if self.first_fee:
            return float(self.first_fee*1000)
        return None
    
    @FirstFee.setter
    def FirstFee(self,value:float):
        if value:
            self.first_fee = value*(1.0/1000.0)

    @property
    def city_list(self)->list[str]:
        transcity_fees = db.session.query(MTransCity).filter(MTransCity.transfee_id==self.id).all()
        if transcity_fees:
            return [fee.city_name for fee in transcity_fees if fee.city_name]
        return []
    
    @property
    def city_ids(self)->list[int]:
        transcity_fees = db.session.query(MTransCity).filter(MTransCity.transfee_id==self.id).all()
        if transcity_fees:
            return [fee.city_id for fee in transcity_fees if fee.city_id]
        return []
    
class MTransport(db.Model):
    """
    运费模板
    """
    __tablename__ = "sp_transport"
    __table_args__ = (
        db.PrimaryKeyConstraint('id',name='sp_transport_pkey'),
        db.Index('sp_transport_shop_id_idx', 'shop_id'),
    )
    id = db.Column(db.BigInteger,autoincrement=True, primary_key=True)
    tenant_id = db.Column(StringUUID, nullable=False,comment="租户ID")
    shop_id = db.Column(StringUUID, nullable=False,comment="店铺ID")
    name = db.Column(db.String(64), nullable=False,comment="运费模板名称")
    charge_type = db.Column(db.String(1), nullable=False,comment="计费方式 （A:按件数 W:按重量 V:按体积）")
    is_free_fee = db.Column(db.Boolean(),server_default=db.text("false"),comment="是否包邮")
    has_free_condition = db.Column(db.Boolean(),server_default=db.text("false"),comment="是否包含包邮条件")
    created_at = db.Column(db.TIMESTAMP,server_default=func.current_timestamp(),comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False,comment="创建人")
    updated_at = db.Column(db.TIMESTAMP, nullable=True,comment="更新时间")
    updated_by = db.Column(StringUUID, nullable=True,comment="更新人")

    @property
    def transfees(self)->list[MTransfee]:
        return db.session.query(MTransfee).filter(MTransfee.transport_id==self.id).all()
    @property
    def transfee_frees(self)->list[MTransfeeFree]:
        return db.session.query(MTransfeeFree).filter(MTransfeeFree.transport_id==self.id).all()